package com.lyn.pluginhost.other


import android.text.TextUtils
import com.lyn.io.file.Folder
import com.lyn.pluginhost.utils.PropUtil
import java.io.File
import java.util.zip.ZipFile

/**
 *
 * @author longyn 2025/07/04
 * @version 1.0.0
 */
internal object SoOperate {

    private const val TAG = "SoUtil"

    /**
     * 获取cpu架构
     *
     * @return cpu架构
     */
    @JvmStatic
    private fun getCPUAbi(): String? {
        return PropUtil.get("ro.product.cpu.abi", "arm64-v8a")
    }

    /**
     * 提取插件so 到指定目录
     *
     * @param pluginFilePath 插件文件路径
     * @return so文件路径
     */
    @JvmStatic
    fun extractPluginSoToTargetFolder(
        pluginFilePath: String, soFolder: Folder
    ): String {
        try {
            val file = File(pluginFilePath)
            val cpuAbi = getCPUAbi()
            if (TextUtils.isEmpty(cpuAbi)) {
                throw NullPointerException("获取当前cpuAbi 失败")
            }
            val zipFile = ZipFile(file)
            val entries = zipFile.entries()
            while (entries.hasMoreElements()) {
                val zipEntry = entries.nextElement()
                val zipEntryName = zipEntry.name
                if (!zipEntryName.startsWith("lib")) {
                    continue
                }
                if (!zipEntryName.contains((cpuAbi)!!)) {
                    continue
                }
                if (!cpuAbi.contains("64")) {
                    if (zipEntryName.contains("64")) {
                        continue
                    }
                }
                if (!zipEntryName.endsWith(".so")) {
                    continue
                }
                val split =
                    zipEntryName.split("/".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
                val soFileName = split[split.size - 1]
                if (TextUtils.isEmpty(soFileName)) {
                    continue
                }
                val inputStream = zipFile.getInputStream(zipEntry)
                soFolder.getFile(soFileName).let {
                    if (it.exists()){
                        it.setWritable(true)
                    }
                }
                val writeFile = soFolder.writeFile(inputStream, soFileName, true)
                writeFile.let { File(it).setReadOnly() }
            }
        } catch (e: Throwable) {
            e.printStackTrace()
        }
        return ""
    }
}